﻿using NLog;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq; // 添加 LINQ 命名空间
using System.Windows;
using System.Windows.Threading;

namespace GameTools.Service.Nlog
{
    public class LogService : ILogService
    {
        private static readonly ILogger _logger = LogManager.GetCurrentClassLogger();
        private readonly ObservableCollection<LogItem> _logItems = new();
        private readonly List<LogItem> _pendingLogs = new();
        private readonly object _lock = new();
        private readonly DispatcherTimer _flushTimer;
        private const int MaxLogItems = 10000; // 最大日志条数
        private const int FlushIntervalMs = 5; // 批量更新间隔（毫秒）

        public ObservableCollection<LogItem> LogItems => _logItems;

        public LogService()
        {
            // 初始化定时器，用于定期刷新日志
            _flushTimer = new DispatcherTimer
            {
                Interval = TimeSpan.FromMilliseconds(FlushIntervalMs)
            };
            _flushTimer.Tick += FlushPendingLogs;
            _flushTimer.Start();
        }

        public void LogInfo(string message) => Log(LogLevel.Info, message);
        public void LogWarn(string message) => Log(LogLevel.Warn, message);
        public void LogError(string message) => Log(LogLevel.Error, message);
        public void LogDebug(string message) => Log(LogLevel.Debug, message);

        private void Log(LogLevel level, string message)
        {
            // 记录到 NLog（线程安全）
            _logger.Log(level, message);

            // 将日志添加到待处理列表
            lock (_lock)
            {
                _pendingLogs.Add(new LogItem
                {
                    Level = level,
                    Message = message,
                    Timestamp = DateTime.Now
                });
            }
        }

        private async void FlushPendingLogs(object sender, EventArgs e)
        {
            // 停止定时器以避免重叠调用
            if (_flushTimer != null)
            {
                _flushTimer.Stop();
            }

            try
            {
                // 获取待处理的日志
                List<LogItem> logsToAdd;
                lock (_lock)
                {
                    if (!_pendingLogs.Any())
                        return;

                    logsToAdd = _pendingLogs.ToList();
                    _pendingLogs.Clear();
                }

                // 在 UI 线程上批量更新 ObservableCollection，使用 Dispatcher.InvokeAsync
                await Application.Current.Dispatcher.InvokeAsync(() =>
                {
                    foreach (var log in logsToAdd)
                    {
                        // 限制日志数量
                        if (_logItems.Count >= MaxLogItems)
                        {
                            _logItems.RemoveAt(0); // 移除最早的日志
                        }

                        _logItems.Add(log);
                    }

                    System.Diagnostics.Debug.WriteLine($"Flushed {logsToAdd.Count} logs, Total: {_logItems.Count}");
                }, DispatcherPriority.Background); // 降低优先级，避免影响 UI 响应
            }
            catch (Exception ex)
            {
                System.Diagnostics.Debug.WriteLine($"Error in FlushPendingLogs: {ex.Message}");
                _logger.Error(ex, "Error in FlushPendingLogs"); // 记录到 NLog
            }
            finally
            {
                // 恢复定时器
                try
                {
                    if (_flushTimer != null)
                    {
                        _flushTimer.Start();
                    }
                }
                catch (Exception ex)
                {
                    System.Diagnostics.Debug.WriteLine($"Error restarting timer: {ex.Message}");
                    _logger.Error(ex, "Error restarting timer in FlushPendingLogs");
                }
            }
        }

        // 清理资源
        public void Dispose()
        {
            if (_flushTimer != null)
            {
                _flushTimer.Tick -= FlushPendingLogs;
                _flushTimer.Stop();
            }

            lock (_lock)
            {
                _pendingLogs.Clear(); // 清空待处理日志
            }
        }
    }

}
